# == Schema Information
# Schema version: 22
#
# Table name: users
#
#  id                        :integer       not null, primary key
#  login                     :string(255)
#  email                     :string(255)
#  crypted_password          :string(40)
#  salt                      :string(40)
#  created_at                :datetime
#  updated_at                :datetime
#  remember_token            :string(255)
#  remember_token_expires_at :datetime
#  first_name                :string(255)
#  last_name                 :string(255)
#  gender                    :string(255)
#  city                      :string(255)
#  state                     :string(255)
#  zip_code                  :string(255)
#  photo_id                  :integer
#  time_zone                 :string(255)   default("Pacific Time (US & Canada)")
#  activation_code           :string(40)
#  activated_at              :datetime
#  visits_count              :integer       default(0)
#  last_login_at             :datetime
#

require 'digest/sha1'
# we need to require the user file here to get around a Rails 2.0 bug that pops up 
# in development mode
#require_dependency File.expand_path(File.dirname(__FILE__) + '/../../vendor/plugins/sourdough/app/models/user')

class User < ActiveRecord::Base
  include AuthenticatedBase

  cattr_reader :per_page
  @@per_page = 10

  has_many :articles, :order => 'created_at DESC'
  has_one  :document, :as => :attachable, :dependent => :destroy
  has_many :memberships, :dependent => :destroy

  attr_accessible :login, :email, :password, :password_confirmation, :time_zone, :activated_at, :activation_code, :first_name, :last_name, :gender, :city, :state, :zip_code, :about, :current_research, :subject_expertise, :courses_taught, :publications, :organizations, :outside_interests, :email_notifications

  validates_presence_of :first_name, :last_name

  has_many :created_disciplines, :class_name => 'Discipline', :dependent => :destroy

  has_many :disciplines, :dependent => :destroy, :through => :memberships do
    def articles
      Article.find(:all,
                   :select => 'articles.*',
                   :joins => 'inner join disciplines on articles.discipline_id = disciplines.id inner join memberships ON disciplines.id = memberships.discipline_id',
                   :conditions => ['memberships.user_id = ?', proxy_owner.id],
                   :limit => 10,
                   :order => 'articles.created_at DESC')
    end
    def discussions
      Discussion.find(:all,
                      :select => 'discussions.*',
                      :joins => 'inner join disciplines on discussions.discipline_id = disciplines.id inner join memberships ON disciplines.id = memberships.discipline_id',
                      :conditions => ['memberships.user_id = ?', proxy_owner.id],
                      :limit => 10,
                      :order => 'discussions.replied_at DESC')
    end
  end

  has_many :discussions

  has_many :friendships_from_me,
           :foreign_key => 'user_id',
           :class_name => 'Friendship', :dependent => :destroy

  has_many :friendships_to_me,
           :foreign_key => 'friend_id',
           :class_name => 'Friendship', :dependent => :destroy

  has_many :friends,
           :through => :friendships_from_me,
           :conditions => 'accepted_at IS NOT NULL',
           :order => :last_name  do
    def articles
      Article.find(:all,
                   :include => [:user => :friendships_from_me],
                   :conditions => ['accepted_at IS NOT NULL and friendships.friend_id = ?', proxy_owner.id],
                   :limit => 10,
                   :order => 'articles.created_at')
    end

  end

  has_many :requested_friendships,
           :through => :friendships_from_me,
           :source => :friend,
           :conditions => 'requested_at IS NOT NULL',
           :order => :requested_at

  has_many :pending_friendships,
           :through => :friendships_to_me,
           :source => :user,
           :conditions => 'requested_at IS NOT NULL',
           :order => :requested_at

  has_many :schools, :dependent => :destroy
  has_many :jobs, :dependent => :destroy
  has_one :current_job, :class_name => "Job", :conditions => 'end_date IS NULL'

  def name
    return [ first_name, last_name ].join(' ') if first_name and not first_name.empty? and last_name and not last_name.empty?
    return [ login, last_name ].join(' ') if last_name and not last_name.empty?
    return first_name if first_name and not first_name.empty?
    return login
  end

  def member_of?(discipline)
    self.memberships.find_by_discipline_id(discipline.id) ? true : false
  end

  def friends_with?(friend)
    self.friends.include? friend
  end

  def request_friendship_with(friend)
    unless self.requested_friendships.include?(friend)
      self.friendships_from_me << Friendship.new(:user_id => self.id, :friend_id => friend.id, :requested_at => Time.now)
    end
  end

  def accept_friendship_request_from(friend)
    transaction do
      self.friendships_from_me << Friendship.new(:user_id => self.id, :friend_id => friend.id, :accepted_at => Time.now)
      friend.friendships_from_me.find_by_friend_id(self.id).update_attributes(:accepted_at => Time.now, :requested_at => nil)
    end
  end

  def decline_friendship_request_from(friend)
    self.friendships_to_me.find_by_user_id(friend.id).destroy
  end

  def withdraw_friendship_request_to(friend)
    self.friendships_from_me.find_by_friend_id(friend.id).destroy
  end

  def destroy_friendship_with(friend)
    transaction do
      friend.friendships_from_me.find_by_friend_id(self.id).destroy
      self.friendships_from_me.find_by_friend_id(friend.id).destroy
    end
  end

  def self.build_advanced_search(query)
    where = self.find_where_options :conditions => 'activated_at IS NOT NULL AND banned_at IS NULL' do |user|
      user.jobs.institution.downcase =~ "%#{query[:institution]}%"
      user.jobs.position.downcase =~ "%#{query[:position]}%"
      user.jobs.department.downcase =~ "%#{query[:department]}%"
      user.city.downcase == query[:city]
    end
    where[:conditions]
  end

  def self.build_profile_lookup(search)
    where = self.find_where_options :conditions => 'activated_at IS NOT NULL AND banned_at IS NULL', :inner => { :user => :or } do |user|
      user.email.downcase == search
      user.first_name.downcase == search.split(" ")[0]
      user.last_name.downcase == search.split(" ")[1]
      user.last_name.downcase == search.split(" ")[0]
      user.login.downcase == search
    end
    where[:conditions]
  end

  def self.build_search(query)
    where = self.find_where_options :conditions => 'activated_at IS NOT NULL AND banned_at IS NULL', :inner => { :user => :or } do |user|
      user.jobs.institution.downcase =~ "%#{query[:institution]}%"
      user.jobs.position.downcase =~ "%#{query[:position]}%"
      user.jobs.department.downcase =~ "%#{query[:department]}%"
      user.city.downcase == query[:city]
      user.email.downcase == query[:email]
      user.first_name.downcase == query[:first_name]
      user.last_name.downcase == query[:last_name]
      user.login.downcase == query[:login]
    end
    where[:conditions]
  end

  def self.with_active
    with_scope(:find => { :conditions => "activated_at IS NOT NULL AND banned_at IS NULL" }) do
      yield
    end
  end

  def self.count_not_banned
    User.with_active do
      User.count
    end
  end

end
